#include <base/Task.hpp>
#include <base/PthreadPool.hpp>
#include <base/reflection.hpp>
#include <base/factory.hpp>
#include <log/log.h>
#include <fcntl.h>
#include <base/FdMap.hpp>
#include <sys/epoll.h>


bool Task::SetNonBlock() 
{
    int flags = fcntl(fd_, F_GETFL, 0);
    flags |= O_NONBLOCK;
    if (fcntl(fd_, F_SETFL, flags) == -1) {
        LogErr("SetNonBlock fcntl error");
        return false;
    }
    return true;
}

void ReadTask::TaskHandler()
{
    LogInfo("ReadTask::TaskHandler task fd:  %d", fd_);
    LogInfo("thread id : %u", std::this_thread::get_id());
    // 读取内容
    std::vector<std::string> buffers;
    ReadTaskReturnType res = util::string::ReadLineNonBlock(fd_, buffers);
    switch (res) {
        case ReadTaskReturnType::SUCCESS: {
            LogInfo("ReadTaskReturnType::SUCCESS");
            struct epoll_event ev;
            ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLONESHOT;
            ev.data.fd = fd_;
            if (epoll_ctl(epollfd_, EPOLL_CTL_MOD, fd_, &ev) == -1) {
                LogErr("add new fd epoll_ctl error");
                close(fd_);
            }
            for (auto& buffer: buffers) {
                LogInfo("TaskHandler read message: %s", buffer.c_str());
                Task* task = new SolveTask(buffer);
                auto thread_pool = PthreadPool::GetInstance();
                thread_pool -> PushTask(task);   
            }
            break;
        }
        case ReadTaskReturnType::CLIENT_CLOSE: {
            for (auto& buffer: buffers) {
                if (!buffer.empty()) {
                    Task* task = new SolveTask(buffer);
                    auto thread_pool = PthreadPool::GetInstance();
                    thread_pool -> PushTask(task);   
                }
            } 
            LogInfo("ReadTaskReturnType::CLIENT_CLOSE");
            LogInfo("epollfd_ = %d, fd_ = %d ", epollfd_, fd_);
            FdMap::GetInstance() -> DelFdMap(fd_); 
            int res = epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd_, nullptr);
            LogInfo("epoll_ctl res = %d", res);
            close(fd_);
            break;
        }
        case ReadTaskReturnType::ERROR: {
            LogInfo("ReadTaskReturnType::ERROR");
            LogInfo("epollfd_ = %d, fd_ = %d ", epollfd_, fd_);
            FdMap::GetInstance() -> DelFdMap(fd_);
            int res = epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd_, nullptr);
            LogInfo("epoll_ctl res = %d", res);
            close(fd_);
            break;
        }
    }

    LogInfo("TaskHandler read message done");
}

void SolveTask::TaskHandler()
{
    // 解析cmdline: cmd args
    std::vector<std::string> cmdline;
    util::string::SplitBySpace(message_, cmdline);
    // 反射类支持 nc -t localhost port <<< "objectname funcname /var/log/....."
    for (auto &i :cmdline) {
        LogInfo(i.c_str());
    }

    if (message_.empty()) return;
    
    try {
        // 先去工厂中查找有无对应object，没有意味着本次先注册对象，然后再设置路径；有的话就意味着本次修改路径
        auto obj = Factory<log::Log>::GetInstance().GetObjectPtr(cmdline[0]);
        if (obj == nullptr)
        {
            LogInfo("not found object");
            return;
        }
        reflect::GetByName(cmdline[0]).GetMemberFunction(cmdline[1]).Invoke(*obj, cmdline[2]); // todo:自适配不同参数类型转换？
    } catch(const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }    

}
